package general;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.Map;

/**
 * Класс для записи логов
 * 
 * @author Last G
 * 
 */
public class Logger
{
	private Map<String, Map<String, String>> config;
	private File file;
	private java.io.PrintStream log;
	private Priority level;

	private enum Priority
	{
		ERROR, WARNING, INFO
	}

	/**
	 * Стандартный конструктор с конфигурациями
	 * 
	 * @param conf
	 *            конфигурации
	 * @throws LoggerException
	 * 			исключение связанное с невозможностью сохранения логов
	 */
	public Logger(Map<String, Map<String, String>> conf) throws LoggerException
	{
		config = conf;
		try
		{
			file = new File(config.get("LOGGER").get("LOGFILE"));
			if (file == null)
			{
				throw new Exception("There is no such option: LOGFILE");
			}
		} catch (Exception e)
		{
			throw new LoggerException("Can't correct parse options:"
					+ e.getLocalizedMessage());
		}

		try
		{
			file.createNewFile();
			log = new PrintStream(new FileOutputStream(file, true));

		} catch (FileNotFoundException e)
		{
			throw new LoggerException(
					"It can't be, but we have FileNotFoundException"
							+ e.getLocalizedMessage());
		} catch (IOException e)
		{
			throw new LoggerException("Can't open or create logfile"
					+ e.getLocalizedMessage());
		}
		try
		{
			String lv = config.get("LOGGER").get("LEVEL").toUpperCase();
			level = Priority.valueOf(lv);
		} catch (Exception e)
		{
			level = Priority.INFO;
			warn("Unknowm log-level. Log level set to INFO");
		}

	}

	/**
	 * Печатает в лог сообщение с приоритетом Предупреждения
	 * 
	 * @param message
	 *            сообщение
	 */
	public void warn(String message)
	{
		say(Priority.WARNING, message);
	}

	/**
	 * Печатает в лог сообщение с приоритетом Ошибки
	 * 
	 * @param message
	 *            сообщение
	 */
	public void error(String message)
	{
		say(Priority.ERROR, message);
	}

	/**
	 * Печатает в лог сообщение с приоритетом Информации
	 * 
	 * @param message
	 *            сообщение
	 */
	public void info(String message)
	{
		say(Priority.INFO, message);
	}

	/**
	 * Печатает в лог сообщение с заданным приоритетом
	 * 
	 * @param prior
	 *            приоритет
	 * @param message
	 *            сообщение
	 */
	public void say(Priority prior, String message)
	{
		if (prior.compareTo(level) < 1)
		{
			synchronized (this)
			{
				java.util.Date now = new java.util.Date();
				log.println(MessageFormat.format("{0}\r\n\t[{1}]{2}",
						new Object[] { now, prior, message }));
			}
		}
	}

	@Override
	protected void finalize() throws Throwable
	{
		log.flush();
		log.close();
		super.finalize();
	}
}
